package com.mpgame;

import io.netty.channel.ChannelHandlerContext;

import com.mpgame.common.network.NetTcpClient;
import com.mpgame.common.proto.*;
import com.mpgame.common.utils.Log;
import com.mpgame.handler.ChatHandler;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

import com.google.protobuf.Message;
import com.mpgame.common.constants.Constants.CPorts;
import com.mpgame.common.manager.HandlerMgr;

import io.netty.channel.SimpleChannelInboundHandler;

public class TestClient {
    public static void main(String[] args) throws Exception {
        GamePacket rsp = sendHttpReq(
                "/verify/login",
                CmdId.LOGIN_REQ,
                LoginReq.newBuilder()
                        .setAcct("test2")
                        .setPwd("1234")
                        .build());
        if (rsp != null) {
            LoginRsp lrsp = LoginRsp.parseFrom(rsp.getData());
            if (lrsp.getJwtToken() != null && !lrsp.getJwtToken().isEmpty()) {
                String jwtToken = lrsp.getJwtToken();
                Log.info("获取到JWT Token：" + jwtToken);
                testTcpConnection(lrsp.getToken());
            }
        }
    }

    private static void testTcpConnection(String token) throws InterruptedException {
        Log.info("测试TCP服务通信...");

        HandlerMgr handlerMgr = new HandlerMgr()
                .registHandler(CmdId.CHAT_RSP, new ChatHandler());

        new NetTcpClient("127.0.0.1", CPorts.GATEWAY_TCP_PORT).connect(new SimpleChannelInboundHandler<GamePacket>() {
            @Override
            public void channelActive(ChannelHandlerContext ctx) {
                GamePacket auth_req = GamePacket.newBuilder()
                        .setCmd(CmdId.GAME_AUTH_REQ)
                        .setData(GameAuthReq.newBuilder()
                                .setToken(token)
                                .setClientVersion("1.0")
                                .build().toByteString())
                        .build();
                ctx.writeAndFlush(auth_req);
                GamePacket testPkt = GamePacket.newBuilder()
                        .setCmd(CmdId.GAME_CHAT_REQ)
                        .setData(
                            GameChatReq.newBuilder()
                            .setContent("test content!im b")
                            .build().toByteString())
                        .build();
                ctx.writeAndFlush(testPkt);
            }

            @Override
            protected void channelRead0(ChannelHandlerContext ctx, GamePacket pkt) {
                Log.info("收到服务器发包：" + pkt);
                handlerMgr.handle(ctx, pkt);

                if (pkt.getCmd() == CmdId.GAME_AUTH_RSP) {
                    try {
                        UserTokenInfoRsp authRsp = UserTokenInfoRsp.parseFrom(pkt.getData());
                        Log.info(authRsp.toString());
                    } catch (Exception e) {
                        Log.err("打印失败：" + e.getMessage());
                    }

                }
            }

            @Override
            public void channelInactive(ChannelHandlerContext ctx) {
                Log.info("客户端连接已断开...服务器主动关闭或网络异常");
            }

            @Override
            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                Log.err("客户端连接异常：" + cause.getMessage());
                cause.printStackTrace();
            }
        });
    }

    /** eg: route="/verify/login" */
    private static GamePacket sendHttpReq(String route, CmdId msgType, Message msg, String jwtToken) {
        try {
            String URL = "http://127.0.0.1:8081/api" + route;
            HttpClient cli = HttpClient.newBuilder()
                    .connectTimeout(Duration.ofSeconds(10))
                    .build();
            byte[] req = GamePacket.newBuilder()
                    .setCmd(msgType)
                    .setData(msg.toByteString())
                    .build()
                    .toByteArray();
            HttpRequest.Builder httpReqBuilder = HttpRequest.newBuilder()
                    .uri(URI.create(URL))
                    .header("Content-Type", "application/x-protobuf")
                    .timeout(Duration.ofSeconds(30))
                    .POST(HttpRequest.BodyPublishers.ofByteArray(req));
            if (jwtToken != null && !jwtToken.isEmpty()) 
                httpReqBuilder.header("Authorization", "Bearer " + jwtToken);
            HttpRequest httpReq = httpReqBuilder.build();
            HttpResponse<byte[]> httpRsp = cli.send(httpReq, HttpResponse.BodyHandlers.ofByteArray());
            if (httpRsp.statusCode() == 200) {
                byte[] rspDat = httpRsp.body();
                GamePacket pkt = GamePacket.parseFrom(rspDat);
                return pkt;
            } else {
                Log.err("HTTP 请求失败，状态码：" + httpRsp.statusCode());
                return null;
            }
        } catch (Exception e) {
            Log.err("发送HTTP请求" + route + "失败：" + e.getMessage());
            return null;
        }
    }
    private static GamePacket sendHttpReq(String route, CmdId msgType, Message msg) {
        return sendHttpReq(route, msgType, msg, null);
    }

    /** 使用GET方式获取数据 */
    private static GamePacket sendHttpReqWithAuth(String route, String jwtToken) {
        try {
            String URL = "http://127.0.0.1:8081/api" + route;
            HttpClient cli = HttpClient.newBuilder()
                    .connectTimeout(Duration.ofSeconds(10))
                    .build();
            
            HttpRequest.Builder httpReqBuilder = HttpRequest.newBuilder()
                .uri(URI.create(URL))
                .header("Accept", "application/x-protobuf")
                .timeout(Duration.ofSeconds(30))
                .GET(); // 使用GET请求
            
            if (jwtToken != null && !jwtToken.isEmpty()) 
                httpReqBuilder.header("Authorization", "Bearer " + jwtToken);
                
            HttpRequest httpReq = httpReqBuilder.build();
            HttpResponse<byte[]> httpRsp = cli.send(httpReq, HttpResponse.BodyHandlers.ofByteArray());
            
            if (httpRsp.statusCode() == 200) {
                byte[] rspDat = httpRsp.body();
                GamePacket pkt = GamePacket.parseFrom(rspDat);
                return pkt;
            } else {
                Log.err("HTTP 请求失败，状态码：" + httpRsp.statusCode());
                return null;
            }
        } catch (Exception e) {
            Log.err("发送HTTP请求" + route + "失败：" + e.getMessage());
            return null;
        }
    }
}